package com.alisls.demo.cas.crm.config;

import com.alisls.demo.cas.crm.filter.LocalUserInfoFilter;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

/**
 * CAS过滤器
 *
 * @author Ke Wang
 */
@Configuration
public class CasFilterConfig {

    /**
     * CAS登录地址
     */
    @Value("${cas.server-url}")
    private String casServerUrl;

    /**
     * 本应用的主机
     */
    @Value("${cas.client-host}")
    private String casClientHost;

    /**
     * 注入单点登录登出监听器 SingleSignOutHttpSessionListener
     * @return 监听器注入
     */
    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean() {
        ServletListenerRegistrationBean listenerRegistrationBean = new ServletListenerRegistrationBean();
        listenerRegistrationBean.setListener(new SingleSignOutHttpSessionListener());
        listenerRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return listenerRegistrationBean;
    }

    /**
     * 注册CAS退出过滤器
     * @return CAS退出过滤器
     */
    @Bean
    public FilterRegistrationBean singleSignOutFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new SingleSignOutFilter());
        registrationBean.setName("CAS Single Sign Out Filter");
        registrationBean.addUrlPatterns("/*");
        registrationBean.addInitParameter("casServerUrlPrefix", casServerUrl);
        registrationBean.setOrder(2);
        return registrationBean;
    }

    /**
     * 注册CAS认证过滤器，负责登录认证
     * @return 认证过滤器
     */
    @Bean
    public FilterRegistrationBean casAuthenticationFilter() {
        AuthenticationFilter authenticationFilter = new AuthenticationFilter();

        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(authenticationFilter);
        filterRegistrationBean.setName("CAS认证过滤器");
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("casServerLoginUrl", casServerUrl);
        filterRegistrationBean.addInitParameter("serverName", casClientHost);
        filterRegistrationBean.setOrder(3);

        return filterRegistrationBean;
    }

    /**
     * 注册CAS令牌校验过滤器
     * @return 令牌校验过滤器
     */
    @Bean
    public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter() {
        Cas20ProxyReceivingTicketValidationFilter cas20ProxyReceivingTicketValidationFilter = new Cas20ProxyReceivingTicketValidationFilter();

        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(cas20ProxyReceivingTicketValidationFilter);
        filterRegistrationBean.setName("CAS令牌校验过滤器");
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("casServerUrlPrefix", casServerUrl);
        filterRegistrationBean.addInitParameter("serverName", casClientHost);
        filterRegistrationBean.setOrder(4);

        return filterRegistrationBean;
    }

    /**
     * 注册HttpServletRequest请求包裹过滤器
     * 比如允许开发者通过HttpServletRequest的getRemoteUser()获取SSO登录的登录名
     *
     * @return 请求包裹过滤器
     */
    @Bean
    public FilterRegistrationBean httpServletRequestWrapperFilter() {
        HttpServletRequestWrapperFilter httpServletRequestWrapperFilter = new HttpServletRequestWrapperFilter();

        FilterRegistrationBean registrationBean = new FilterRegistrationBean(httpServletRequestWrapperFilter);
        registrationBean.setFilter(httpServletRequestWrapperFilter);
        registrationBean.setName("CAS HttpServletRequest Wrapper Filter");
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(5);
        return registrationBean;
    }

    /**
     * 注册单点登录本地用户信息过滤器
     *
     * @return 单点登录本地用户信息过滤器
     */
    @Bean
    public FilterRegistrationBean localUserInfoFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setName("localUserInfoFilter");
        registrationBean.setFilter(new LocalUserInfoFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(6);
        return registrationBean;
    }

}
